import Utils from '../utils/index';

class TimeRange {
    constructor(Gantt, options) {
        this.currentRange = []; // 当前数据范围
        this.showRange = []; // 当前显示的范围
        this.timeRange = null; // 所有数据范围
        this.timeRangeHours = 0; // 数据请求范围

        // 内部变量
        this.dragMax = 0;
        this.dragMin = Infinity;

        this.Gantt = Gantt;
    }

    // 返回当前的时间范围，用于定时更新数据的参数
    get() {
        if (this.timeRange.history.length > 0) {
            return this.timeRange.history.concat(this.timeRange.current)
        }
        return [this.timeRange.current];
    }

    // 合并时间范围
    mergeTime(range, targetRange) {
        let nodataRange = null;
        if (range[0] < targetRange[0]) { // 左侧扩展    x a x2 b
            nodataRange = [range[0], targetRange[0]];
            targetRange[0] = range[0]
        } else if (range[1] > targetRange[1]) { // 右侧扩展 a x b x2
            nodataRange = [targetRange[1], range[1]];
            targetRange[1] = range[1];
        }
        return nodataRange;
    }

    // 判断时间范围是否有重合
    hasOverlay(range, range2) {
        return !(range[0] > range2[1] || range[1] < range2[0])
    }

    // 增加时间范围
    addTimeRange(range, isAdd) {
        let nodataRange = null;

        if (!this.timeRange) {
            this.timeRange = {
                current: range, // 当前的范围
                history: []     // 历史的范围，注意是排好序的
            }
        } else {

            if (isAdd) { // 时间跳转

                // 1. 判断是否和当前范围有有重叠，如果有，则执行合并
                if (this.hasOverlay(range, this.timeRange.current)) { // 有重叠
                    nodataRange = this.mergeTime(range, this.timeRange.current);
                } else {

                    let i = 0,
                        total = this.timeRange.history.length,
                        historyOverlay = false;
                    if (total > 0) {
                        for (; i < total; i++) {
                            if (this.hasOverlay(range, this.timeRange.history[i])) {
                                // 2. 判断是否和历史范围有重叠，如果有，对有重叠的部分进行合并，并将当前 current push 到 history 中，该历史范围提取为 current
                                historyOverlay = true;
                                let temp = Utils.JSONCopy(this.timeRange.history[i]);
                                nodataRange = this.mergeTime(range, temp);
                                this.timeRange.history.push(Utils.JSONCopy(this.timeRange.current));
                                this.timeRange.current = temp;
                                this.timeRange.history.splice(i, 1);
                                break;
                            }
                        }
                    }

                    // 3. 并将当前 current push 到 history 中，当前的 range 设置为 current
                    if (!historyOverlay) {
                        this.timeRange.history.push(Utils.JSONCopy(this.timeRange.current));
                        this.timeRange.current = range;
                        nodataRange = range;
                    }
                }

            } else { // 拖动
                nodataRange = this.mergeTime(range, this.timeRange.current);
            }
        }

        // TODO: 检查历史时间是否可以合并
        // console.log(this.timeRange);
        return nodataRange;
    }

    // 刷新操作，根据当前时间范围，反推加载数据的时间
    refresh() {
        let centerTime = this.showRange[0] + (this.showRange[1] - this.showRange[0]) / 2,
            offset = this.timeRangeHours / 2,
            timeRange = [centerTime - offset, centerTime + offset];

        this.timeRange = {
            current: timeRange,
            history: []
        };
        return timeRange;
    }

    // 时间跳转
    goto(time) {
        if (typeof time === 'string') {
            time = new Date(time).getTime();
        }
        let timeRange = [time - this.timeRangeHours / 2, time + this.timeRangeHours / 2],
            showRangeOffset = (this.showRange[1] - this.showRange[0]) / 2;
        this.showRange = [time - showRangeOffset, time + showRangeOffset];

        timeRange = this.addTimeRange(timeRange, true);

        return timeRange;
    }

    resetTime(x) {
        return this.calcTime(new Date().getTime(), x);
    }

    calcTime(firstTime, x) {
        let timeRange = Utils.calcTime(firstTime, x);

        this.addTimeRange(timeRange);

        this.timeRangeHours = timeRange[1] - timeRange[0];

        let showHours = Math.round((
            (this.Gantt.chart && this.Gantt.chart.plotWidth) || (window.innerWidth - 100))
             / 150 / 2), // 每个小时的刻度间隔是 150 像素
            centerTimeRange = Utils.timeRound(firstTime || new Date().getTime(), Utils.timeUnit.hours, true),
            offset = showHours * Utils.timeUnit.hours;

        this.showRange = [centerTimeRange - offset , centerTimeRange + offset];

        return timeRange;
    }

    // 拖动时计算需要加载数据的范围
    setShowRange(min, max, callback) {
        if (this.dragTimer) {
            clearTimeout(this.dragTimer);
        }
        if (min < this.dragMin) {
            this.dragMin = min;
        }
        if (max > this.dragMax) {
            this.dragMax = max;
        }

        this.showRange = [min, max];

        this.dragTimer = setTimeout(() => {
            callback(this.addTimeRange(this.showRange));
        }, 100);
    }

    // 修复当前时间范围，用于加载数据时，返回的数据范围超过给定的参数范围
    fixedRange(min, max) {
        if (this.timeRange.current[0] > min) {
            this.timeRange.current[0] = min;
        }
        if (this.timeRange.current[1] < max) {
            this.timeRange.current[1] = max;
        }
    }

    // 获取当前视图内的图块
    getCurrentPoints(clearConflict, ignoreStationNo) {
        let points = {},
            facility = null,
            facilityKey = null;
        this.Gantt.chart.series.forEach(series => {
            if (series.options.extra && series.options.extra.min > this.showRange[1] && series.options.extra.max < this.showRange[0]) {
                return;
            }

            series.points.forEach(point => {
                // 判断图块是否在当前显示的范围内
                if (
                    (point.x >= this.showRange[0] && point.x <= this.showRange[1]) ||
                    (point.x2 >= this.showRange[0] && point.x2 <= this.showRange[1])
                ) {

                    facilityKey = point.extra.facilityNo;
                    facility = Utils.facilities[Math.floor(point.y)];

                    if (!ignoreStationNo && facility.facilityType === 'D') {
                        facilityKey += (point.extra.stationNo||1);
                        if(!point.extra.stationNo) {
                            console.log(point, 'nostationNo');
                        }
                    }


                    if (!points[facilityKey]) {
                        points[facilityKey] = [];
                    }
                    if (clearConflict) {
                        point.update({
                            xConflicted: undefined,// 图块冲突（x 方向）
                            sConflicted: undefined, // 连线冲突（ s 为 series）
                            cConflicted: undefined, // 铸机冲突 （ccm）
                            caConflict: undefined, // 钢种冲突（ ca）
                            rConflicted: undefined // 设备维修冲突 （ repair）
                        }, false);
                        // point.updateConflictStates();
                    }
                    points[facilityKey].push(point);
                }
            });
        });
        return Utils.isObjEmpty(points) ? null : points;
    }

    // 获取当前视图内的数据列
    getCurrentSeries() {
        let series = [];
        this.Gantt.chart.series.forEach(serie => {
            if (serie.options.extra && (
                serie.options.extra.min >= this.showRange[0] || serie.options.extra.max <= this.showRange[1]
            )) {
                series.push(serie);
            }
        });

        return series.length > 0 ? series : null;
    }

    // 获取当前时间范围内的设备检修数据
    getCurrentFacilityRepairs(callback) {
        let facilityNoRepairs = {},
            start = null,
            end = null,
            repairs = this.Gantt.cache.getAll('facilityRepairs');

        if (repairs && repairs.length > 0) {
            repairs.forEach(repair => {
                start = new Date(repair.repairStartTmstamp).getTime();
                end = new Date(repair.repairEndTmstamp).getTime();
                if (start >= this.showRange[1] || end <= this.showRange[0]) {
                    return;
                }

                // 计算交集
                if (start < this.showRange[0]) {
                    start = this.showRange[0];
                }

                if (end > this.showRange[1]) {
                    end = this.showRange[1];
                }
                facilityNoRepairs[repair.sid] = [repair.facilityNo, start, end];
            });
        }

        return Utils.isObjEmpty(facilityNoRepairs) ? null : facilityNoRepairs
    }

   //  // 居中显示指定的范围
   //  centerByRange(range) {
   //      let centerTime = range[0] + (range[1] - range[0]) / 2,
   //          offset = (this.showRange[1] - this.showRange[0]) / 2;
   //      this.showRange[0] = centerTime - offset;
   //      this.showRange[1] = centerTime + offset;
   //  }
}

export default TimeRange;